﻿(*  
    F# Dataflow for ViewModels
    (c) Andras Janko, 2013, Available under Microsoft Public License.
*)

namespace FsFlow

open System
//open System.Collections.Generic

[<AutoOpen>]
module Operators =
    // extended functionality for ! and :=
    let inline (!) (o: ^x) = (^x: (member Value: _ with get) o)
    let inline (:=) (o: ^x) v = (^x: (member Value: _ with set) (o, v))
    let inline (==) o1 o2 = obj.Equals(o1, o2)
    let inline (!=) o1 o2 = not <| obj.Equals(o1, o2) 
    let inline (===) o1 o2 = obj.ReferenceEquals(o1, o2)
    let inline dispose (o: IDisposable) = o.Dispose()
    let inline (|>!) x f = f x |> ignore; x

module Option = 
    let ofNull source = if obj.ReferenceEquals(source, null) then None else Some source
    let ofNullable (source: Nullable<_>) = if source.HasValue then Some source.Value else None
    let getOrDefault defaultValue option = match option with None -> defaultValue | Some o -> o

module Null =
    let ofOption option = match option with None -> Unchecked.defaultof<_> | Some v -> v

module Nullable =
    let ofOption option =
        match option with None -> Nullable() | Some o -> Nullable o

module Map =
    let byKey projection source = source |> Seq.map(fun e -> projection e, e) |> Map.ofSeq    
    let byKeyVal projection source = source |> Seq.map projection |> Map.ofSeq    
    let byVal mapping source = source |> Seq.map (fun e -> e, mapping e) |> Map.ofSeq 
    let keys m = m |> Map.toSeq |> Seq.map fst
    let values m = m |> Map.toSeq |> Seq.map snd

type Ticket = uint32

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] 
module Ticket =   
    let [<Literal>] zero = 0u
    let inline nextId t = t + 1u
    let inline compNextDepth t = t + 1u
    let inline compNextId t = t + 0x10u
    let inline ofLevel (l: byte) = 0x80000000u + (uint32 l <<< 27)
    let [<Literal>] maxLevel = 0x10uy      

//type Ticket = uint64
//
//[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>] 
//module Ticket =   
//    let zero = 0UL
//    let nextId t = t + 1UL
//    let compNextDepth t = t + 1UL
//    let compNextId t = t + 0x40UL
//    let ofLevel (l: byte) = 0x8000000000000000UL + (uint64 l <<< 57)
//    let maxLevel = 0x40UL      
